package com.lyw.gulimall.product.service.impl;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lyw.common.constant.ProductConstant;
import com.lyw.gulimall.product.dao.AttrAttrgroupRelationDao;
import com.lyw.gulimall.product.dao.AttrGroupDao;
import com.lyw.gulimall.product.dao.CategoryDao;
import com.lyw.gulimall.product.entity.AttrAttrgroupRelationEntity;
import com.lyw.gulimall.product.entity.AttrGroupEntity;
import com.lyw.gulimall.product.entity.CategoryEntity;
import com.lyw.gulimall.product.service.CategoryService;
import com.lyw.gulimall.product.vo.AttrRespVo;
import com.lyw.gulimall.product.vo.AttrVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.lyw.gulimall.product.dao.AttrDao;
import com.lyw.gulimall.product.entity.AttrEntity;
import com.lyw.gulimall.product.service.AttrService;
import org.springframework.transaction.annotation.Transactional;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Autowired
    private AttrAttrgroupRelationDao attrAttrgroupRelationDao;

    @Autowired
    private CategoryDao categoryDao;

    @Autowired
    private AttrGroupDao attrGroupDao;

    @Autowired
    private CategoryService categoryService;

    @Override
    @Transactional
    public IPage<Map<String, Object>> queryPage(Integer page, Integer limit, String name) {

        Page<AttrEntity> result = new Page<>(page, limit);
        LambdaQueryWrapper<AttrEntity> lqw = new LambdaQueryWrapper<>();

        // 搜索条件
        if (StringUtils.isNotBlank(name)) {
            lqw.and(wrapper -> {
                wrapper.eq(AttrEntity::getAttrId , name).or().like(AttrEntity::getAttrName, name);
            });
        }
        IPage<Map<String, Object>> list = baseMapper.selectPageList(result, lqw);

        return list;
    }

    @Override
    @Transactional
    public IPage<AttrRespVo> queryAttrBasePage(Long catelogId, Integer page, Integer limit, String name, String type) {

        Page<AttrEntity> result = new Page<>(page, limit);
        LambdaQueryWrapper<AttrEntity> lqw = new LambdaQueryWrapper<>();

        lqw.eq(AttrEntity::getAttrType, "base".equalsIgnoreCase(type) ? ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() : ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode());
        // 满足条件查找某一类别的所有属性
        if (catelogId != 0) {
            lqw.eq(AttrEntity::getCatelogId, catelogId);
        }

        // 搜索条件
        if (StringUtils.isNotBlank(name)) {
            lqw.and(wrapper -> {
                wrapper.eq(AttrEntity::getAttrId , name).or().like(AttrEntity::getAttrName, name);
            });
        }
        IPage<AttrEntity> list = baseMapper.selectAttrBasePageList(result, lqw);
        List<AttrEntity> records = list.getRecords();

        /*
            因为返回的对象不止包括属性表中的信息，还需要属性分组中的信息，所以这里通过找到属性、分组关联表中的分组id找到对应的表信息
         */
        // 遍历查到的数据
        List<AttrRespVo> collect = records.stream().map(attrEntity -> {

            // 准备响应对象
            AttrRespVo respVo = new AttrRespVo();
            // 复制相同属性里的值
            BeanUtils.copyProperties(attrEntity, respVo);
            // 通过分类id获取分类名
            CategoryEntity categoryEntity = categoryDao.selectById(attrEntity.getCatelogId());
            if (categoryEntity != null) {
                respVo.setCatelogName(categoryEntity.getName());
            }

            // 使用属性id在中间表找到属性分组id
            AttrAttrgroupRelationEntity relationEntity =
                    attrAttrgroupRelationDao
                            .selectOne(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrId, attrEntity.getAttrId()));
            // 不为空，通过属性分组id找到属性名
            if ("base".equalsIgnoreCase(type)) {
                if (relationEntity != null && relationEntity.getAttrGroupId() != null) {
                    AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(relationEntity.getAttrGroupId());
                    respVo.setAttrGroupId(attrGroupEntity.getAttrGroupId());
                    respVo.setGroupName(attrGroupEntity.getAttrGroupName());
                }
            }
            // 返回对象
            return respVo;
        }).collect(Collectors.toList());

        IPage<AttrRespVo> pages = new Page<>(page, limit);
        BeanUtils.copyProperties(list, pages);
        pages.setRecords(collect);
        return pages;
    }

    @Override
    @Transactional
    public AttrRespVo getAttrInfo(Long attrId) {
        // 获取当前属性表中的信息
        AttrEntity attrEntity = this.getById(attrId);
        // 将数据复制到要响应的对象中
        AttrRespVo respVo = new AttrRespVo();
        BeanUtils.copyProperties(attrEntity, respVo);

        // 封装属性分组名和分类级联路径
        // 1. 通过属性id查询属性、分组关联表中的属性关联实体，用于获取分组实体中的分组名
        if (attrEntity.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) {
            AttrAttrgroupRelationEntity relationEntity =
                    attrAttrgroupRelationDao
                            .selectOne(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrId, attrEntity.getAttrId()));
            if (relationEntity != null) {
                respVo.setAttrGroupId(relationEntity.getAttrGroupId());
                AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(relationEntity.getAttrGroupId());
                if (attrGroupEntity != null) {
                    respVo.setGroupName(attrGroupEntity.getAttrGroupName());
                }
            }
        }

        // 2. 通过属性实体中的分类id获取分类实体
        CategoryEntity categoryEntity = categoryDao.selectById(attrEntity.getCatelogId());
        // 通过分类业务中的方法找到路径
        Long[] catelogPath = categoryService.findCatelogPath(attrEntity.getCatelogId());
        if (categoryEntity != null) {
            respVo.setCatelogName(categoryEntity.getName());
        }
        respVo.setCatelogPath(catelogPath);
        return respVo;
    }

    @Override
    @Transactional
    public void updateAttr(AttrVo attr) {
        // 基本更新
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr, attrEntity);
        this.updateById(attrEntity);

        // 修改分组关联
        // 如果当前分组类型是基本类型的话就执行一下操作
        if (attrEntity.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) {
            Integer count = attrAttrgroupRelationDao.selectCount(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrId, attr.getAttrId()));

            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrGroupId(attr.getAttrGroupId());
            relationEntity.setAttrId(attr.getAttrId());

            // 判断数据库是否有记录，有的话就是更新，没有的话就插入一条记录
            if (count > 0) {
                attrAttrgroupRelationDao.update(relationEntity, new LambdaUpdateWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrId, attr.getAttrId()));
            } else {
                attrAttrgroupRelationDao.insert(relationEntity);
            }
        }
    }

    /**
     * 根据分组Id获取到基本属性信息
     * @param attrgroupId
     * @return
     */
    @Override
    public List<AttrEntity> getRelationAttr(Long attrgroupId) {

        // 通过关联表获取到属性id
        List<AttrAttrgroupRelationEntity> relationEntities = attrAttrgroupRelationDao
                .selectList(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
                        .eq(AttrAttrgroupRelationEntity::getAttrGroupId, attrgroupId));

        if (relationEntities.size() <= 0) {
            return null;
        }

        List<Long> attrIds = relationEntities.stream().map(attr -> attr.getAttrId()).collect(Collectors.toList());
        List<AttrEntity> attrEntities = this.listByIds(attrIds);
        return attrEntities;
    }

    /**
     * 在这些属性中找到能被检索的属性 search_type = 1
     * @param attrIds
     * @return
     */
    @Override
    public List<AttrEntity> selectSearchAttrIds(List<Long> attrIds) {

        return baseMapper.selectSearchAttrIds(attrIds);
    }

    @Override
    @Transactional
    public void saveAttr(AttrVo attr) {
        // 1、保存 Attr 表中的基本信息
        AttrEntity attrEntity = new AttrEntity();
        // 复制属性值
        BeanUtils.copyProperties(attr, attrEntity);
        this.save(attrEntity);

        // 2、保存 Attr 的关联信息
        if (attr.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() && attr.getAttrGroupId() != null) {
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrGroupId(attr.getAttrGroupId());
            relationEntity.setAttrId(attrEntity.getAttrId());
            attrAttrgroupRelationDao.insert(relationEntity);
        }
    }

}
